package com.example.adminframework.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;


/**
 * 时间工具类
 *
 * @author qinweisi
 * @date 2020-11-04 13:30:00
 */
public class DateUtil {

    // 年-月-日 时:分:秒
    public static String TIME_HMS = "yyyy-MM-dd HH:mm:ss";
    // 年-月-日
    public static String YYYY_MM_DD = "yyyy-MM-dd";
    // 时分秒
    public static String HH_mm_ss = "HH:mm:ss";

    // 年月日时分
    public static String YYYYMMDDHHMM = "yyyyMMddHHmm";

    /**
     * 设置开始时间
     *
     * @param calendar 日历
     */
    public static void setStartTime(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
    }

    /**
     * 设置结束时间
     *
     * @param calendar 日历
     */
    public static void setEndTime(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
    }


    /**
     * 获取今天开始时间
     */
    public static Long getTodayStartTime() {
        Calendar calendar = Calendar.getInstance();
        setStartTime(calendar);
        return calendar.getTimeInMillis();
    }

    /**
     * 昨天开始时间
     *
     * @return {@link Long}
     */
    public static Long getYesterdayStartTime() {
        Calendar calendar = Calendar.getInstance();
        setStartTime(calendar);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        return calendar.getTimeInMillis();
    }


    /**
     * 昨天结束时间
     *
     * @return {@link Long}
     */
    public static Long getYesterdayEndTime() {
        return getTodayStartTime() - 1;
    }

    /**
     * 本周开始时间
     *
     * @return {@link Long}
     */
    public static Long getThisWeekStartTime() {
        Calendar calendar = Calendar.getInstance();
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == 0) {
            calendar.set(Calendar.DAY_OF_WEEK_IN_MONTH, -1);
        }
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        setStartTime(calendar);
        return calendar.getTimeInMillis();
    }

    /**
     * 上周开始时间
     *
     * @return {@link Long}
     */
    public static Long getLastWeekStartTime() {
        Calendar calendar = Calendar.getInstance();
        int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
        if (dayOfWeek == 0) {
            calendar.set(Calendar.DAY_OF_WEEK_IN_MONTH, -1);
        }
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        setStartTime(calendar);
        calendar.add(Calendar.DAY_OF_MONTH, -7);
        return calendar.getTimeInMillis();
    }


    /**
     * 上周结束时间
     *
     * @return {@link Long}
     */
    public static Long getLastWeekEndTime() {
        return getThisWeekStartTime() - 1;
    }

    /**
     * 本月开始时间
     *
     * @return {@link Long}
     */
    public static Long getThisMonthStartTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        setStartTime(calendar);
        return calendar.getTimeInMillis();
    }

    /**
     * 上月开始时间
     *
     * @return {@link Long}
     */
    public static Long getLastMonthStartTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        setStartTime(calendar);
        return calendar.getTimeInMillis();
    }

    /**
     * 上月结束时间
     *
     * @return {@link Long}
     */
    public static Long getLastMonthEndTime() {
        return getThisMonthStartTime() - 1;
    }

    /**
     * 本季度开始时间
     *
     * @return {@link Long}
     */
    public static Long getThisQuarterStartTime() {
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(Calendar.MONTH);
        int quarter = month / 3;
        int startMonth = 0;
        if (quarter == 1) {
            startMonth = 3;
        } else if (quarter == 2) {
            startMonth = 6;
        } else if (quarter == 3) {
            startMonth = 9;
        }
        calendar.set(Calendar.MONTH, startMonth);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        setStartTime(calendar);
        return calendar.getTimeInMillis();
    }

    /**
     * 上季度开始时间
     *
     * @return {@link Long}
     */
    public static Long getLastQuarterStartTime() {
        Calendar calendar = Calendar.getInstance();
        int month = calendar.get(Calendar.MONTH);
        int quarter = month / 3;
        int startMonth = 0;
        if (quarter == 1) {
            startMonth = 3;
        } else if (quarter == 2) {
            startMonth = 6;
        } else if (quarter == 3) {
            startMonth = 9;
        }
        if (startMonth == 0) {
            calendar.set(Calendar.MONTH, 9);
            calendar.add(Calendar.YEAR, -1);
        } else {
            calendar.set(Calendar.MONTH, startMonth - 3);
        }
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        setStartTime(calendar);
        return calendar.getTimeInMillis();
    }

    /**
     * 上季度结束时间
     *
     * @return {@link Long}
     */
    public static Long getLastQuarterEndTime() {
        return getThisQuarterStartTime() - 1;
    }

    /**
     * 今年开始时间
     *
     * @return {@link Long}
     */
    public static Long getThisYearStartTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        setStartTime(calendar);
        return calendar.getTimeInMillis();
    }

    /**
     * 去年开始时间
     *
     * @return {@link Long}
     */
    public static Long getLastYearStartTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, -1);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        setStartTime(calendar);
        return calendar.getTimeInMillis();
    }

    /**
     * 去年结束时间
     *
     * @return {@link Long}
     */
    public static Long getLastYearEndTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        setStartTime(calendar);
        calendar.add(Calendar.MILLISECOND, -1);
        return calendar.getTimeInMillis();
    }

    /**
     * 格式化日期
     *
     * @param date    日期
     * @param pattern 日期格式
     *                eg:yyyy-MM-dd HH:mm:ss
     * @return 日期字符串
     */
    public static String format(Date date, String pattern) {
        SimpleDateFormat sd = new SimpleDateFormat(pattern);
        return sd.format(date);
    }

    /**
     * 格式化日期
     *
     * @param date    日期字符串
     * @param pattern 日期格式
     *                eg:yyyy-MM-dd HH:mm:ss
     * @return 日期
     * @throws ParseException 解析异常
     */
    public static Date parse(String date, String pattern) throws ParseException {
        SimpleDateFormat sd = new SimpleDateFormat(pattern);
        try {
            return sd.parse(date);
        } catch (ParseException e) {
            throw e;
        }
    }

    /**
     * 获取前后自定义时间
     *
     * @param date    时间
     *                eg: 2020-11-04 12:00:00
     * @param n       前后加减数
     *                eg: 1
     * @param addType 前后加减格式
     *                eg: Calendar.MONTH
     * @param format  自定义格式化
     *                eg: yyyy-MM-dd HH:mm:ss
     * @return eg: 2020-12-04 12:00:00
     */
    public static String beforeOrAfter(Date date, int n, int addType, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        // 前后加减 n
        c.add(addType, n);
        return sdf.format(c.getTime());
    }

    /**
     * 在一定时间范围(begin~end)内,根据类型(type),间隔(n),获取自定义格式(format)的所有片段
     *
     * @param begin  开始时间
     * @param end    结束时间
     * @param type   类型
     *               eg: Calendar.MONTH
     * @param n      间隔
     *               eg: 1
     * @param format 格式化
     * @return eg: [201912, 202001, 202002, 202003]
     */
    public static String[] getAll(Date begin, Date end, int type, int n, String format) {
        List<String> time = new ArrayList<>();
        Calendar c1 = Calendar.getInstance();
        c1.setTime(begin);
        SimpleDateFormat sf = new SimpleDateFormat(format);
        while (c1.getTime().getTime() <= end.getTime()) {
            time.add(sf.format(c1.getTime()));
            c1.add(type, n);
        }
        String[] s = new String[time.size()];
        for (int i = 0; i < time.size(); i++) {
            s[i] = time.get(i);
        }
        return s;
    }

    /**
     * 获取当前
     *
     * @param type 类型
     *             eg:Calendar.YEAR 获取当前年份
     * @return eg: 2020
     */
    public static int getCurrent(int type) {
        Calendar calendar = Calendar.getInstance();
        return calendar.get(type);
    }


    /**
     * 时间补全
     *
     * @param start 开始日期
     *              eg: 2020-11-13
     * @param end   结束日期
     *              eg: 2020-11-13
     * @return eg: 2020-11-13 00:00:00 2020-11-13 23:59:59
     */
//    public static String timeCompletion(String start, String end) {
//        String startTime = " 00:00:00";
//        String endTime = " 23:59:59";
//        if (StringUtils.isNotBlank(start) && StringUtils.isNotBlank(end)) {
//            start = start + startTime;
//            end = end + endTime;
//        } else if (StringUtils.isNotBlank(start) && StringUtils.isBlank(end)) {
//            String time = start;
//            start = time + startTime;
//            end = time + endTime;
//        } else if (StringUtils.isBlank(start) && StringUtils.isNotBlank(end)) {
//            String time = end;
//            start = time + startTime;
//            end = time + endTime;
//        } else {
//            return null;
//        }
//        return start + "~" + end;
//    }

    /**
     * String 类型的日期从旧的格式转换成新的格式
     *
     * @param dateStr
     * @param oldPattern
     * @param newsPattern
     * @return
     */
    public static String getDateStr(String dateStr, String oldPattern, String newsPattern) {
        try {
            SimpleDateFormat oldFormat = new SimpleDateFormat(oldPattern);
            Date str = oldFormat.parse(dateStr);
            SimpleDateFormat dateFormat = new SimpleDateFormat(newsPattern);
            return dateFormat.format(str);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * 判断在某个时间是否在某个时间段内
     *
     * @param selfDate  自定义日期
     * @param startDate 开始时间
     * @param endDate   结束时间
     *                  startDate 肯定小于 endDate 的情况下 判断的不等式成立
     */
    public static boolean isExist(Date selfDate, Date startDate, Date endDate) {
        int x = selfDate.compareTo(startDate) + selfDate.compareTo(endDate);
        return x >= -1 && x <= 1;
    }

    /**
     * 比较
     * 表达式 before >= after ? false : true
     *
     * @param before 大于号前的时间
     * @param after  大于号后的时间
     * @return
     */
    public static boolean compare(Date before, Date after) {
        int x = before.compareTo(after);
        if (x >= 0) {
            return false;
        }
        return true;
    }

    /**
     * 计算相差的月数
     *
     * @param startDate 开始时间
     * @param endDate   结束时间
     * @return
     */
    public static Integer getDifMonth(Date startDate, Date endDate) {
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        start.setTime(startDate);
        end.setTime(endDate);
        int result = end.get(Calendar.MONTH) - start.get(Calendar.MONTH);
        int month = (end.get(Calendar.YEAR) - start.get(Calendar.YEAR)) * 12;
        return Math.abs(month + result);
    }

    /**
     * 获取指定时间的所在月份的最后一天
     *
     * @param date    时间参数
     * @param format1 入参的格式
     * @param format2 结果的格式
     * @return
     */
    public static String getMonthLastDay(String date, String format1, String format2) {
        SimpleDateFormat sdf1 = new SimpleDateFormat(format1);
        Calendar c = Calendar.getInstance();
        try {
            c.setTime(sdf1.parse(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        // 指定月的最后一天
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        // 时
        c.set(Calendar.HOUR_OF_DAY, 23);
        // 分
        c.set(Calendar.MINUTE, 59);
        // 秒
        c.set(Calendar.SECOND, 59);
        SimpleDateFormat sdf2 = new SimpleDateFormat(format2);
        return sdf2.format(c.getTime());
    }

    /**
     * 比较String类型的时间
     * @return
     */
    public static boolean compareTime(Date lastTime , int day){
        String lastDate = beforeOrAfter(lastTime, day, Calendar.DAY_OF_YEAR, DateUtil.TIME_HMS);//最后有效时间
        String date = DateUtil.format(new Date(),DateUtil.TIME_HMS);//当前时间
        if (date.compareTo(lastDate) < 0){
            return true;
        }
        return false;
    }

    /**
     * @param mss 毫秒
     * @return 毫秒数转换为 * 天 * 时 * 分 * 秒 的格式
     */
    public static String formatDuring(long mss) {
        long days = mss / (1000 * 60 * 60 * 24);
        long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
        long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60);
        long seconds = (mss % (1000 * 60)) / 1000;
        return days + " 天 " + hours + " 时 " + minutes + " 分 " + seconds + " 秒 ";
    }
}
